---
--- 灰度处理 根据用户筛选 规则具体实现
--- Created by E.T.
--- DateTime: 2018/11/12 17:41
---
local http_tools = require "kong.plugins.gray.tools.http_tools"
local string_tools = require "kong.plugins.gray.tools.string_tools"
local redis_tools = require "kong.plugins.gray.tools.redis_tools"
local config = require "kong.plugins.gray.tools.config"
local cjson = require "cjson"
local service = kong.service
local request = kong.request
local log = kong.log

local opts = {
    ttl = config.apps_data_ttl,
}
local conf
local _M = {}

--从body参数里面获取token
local function get_body_token()
    local body, err, mimetype = request.get_body()
    if mimetype == config.mimetype_json then
        return body.requestHead.token
    end
    --多媒体文本 目前没有传token
    --if mimetype == config.mimetype_multipart then
    --    return body.token
    --end
end

--从redis获取上游应用名称
local function load_upstream_name()
    redis_tools.init(conf.redis_cluster_nodes)
    local value = redis_tools.get_from_redis(config.env_appname_key)
    redis_tools.close()
    log.notice("redis上游应用：", value)
    return cjson.decode(value)
end
--获取上游应用名称
local function get_upstream_name(key)
    local value, err = kong.cache:get(config.upstream_name_cache_key, opts, load_upstream_name, nil)
    if err then
        log.err("没有从缓存中获取到灰度上游名称信息：", err)
        return nil
    end
    --获取缓存值（检查是否缓存成功）
    --for tk, tv in pairs(value) do
    --    log.notice("app->", tk, tv)
    --end
    return value[key]
end
--从redis获取灰度用户token
local function load_gray_token(token)
    redis_tools.init(conf.redis_cluster_nodes)
    local value = redis_tools.get_from_redis(config.oms_gray_user .. token)
    redis_tools.close()
    log.notice("redis灰度用户：", value)
    return cjson.decode(value)
end

--判断是否灰度用户
local function is_gray_user(token)
    local value, err = kong.cache:get(config.gray_users_cache_key .. token, opts, load_gray_token, token)
    if err then
        --log.err("没有从缓存中获取到灰度用户信息：", err)
        return false
    end
    --获取缓存值（检查是否缓存成功）
    --for tk, tv in pairs(value) do
    --    log.notice("app->", tk, tv)
    --end
    --这里还可以判断用户的token是否一致，目前来看没必要判断，因为能通过token获取到值就证明是灰度用户了
    return true
end

--跳转至上游服务
local function set_upstream(upstream_name, app_key, path)
    if upstream_name == nil then
        upstream_name = "xhg-api"
    end
    service.request.set_path(config.gateway_context_path .. path)
    local ok, err = service.set_upstream(upstream_name)
    if not ok then
        log.err("未找到zuul上游服务：", err)
        local upstream = get_upstream_name(app_key)
        log.err("未找到zuul上游服务,正在跳转至灰度上游...", upstream .. "-gray")
        if upstream ~= nil then
            service.request.set_path(path)
            local code, error = service.set_upstream(upstream .. "-gray")
            if not code then
                log.err("未找到灰度应用上游服务：", error)
                http_tools.response(403, "没有找到[" .. upstream .. "-gray" .. "]上游服务")
            end
        end
    end
end

local function do_users()
    local token = request.get_header("token")
    local host = request.get_host()
    local path = request.get_path()
    --获取环境域名
    local host_name = string_tools.split(host, ".")
    --获取context_path
    local context_path = string_tools.split(path, "/")
    log.notice("请求host->", host)
    log.notice("请求路径->", path)
    if token == nil then
        token = get_body_token()
    end
    log.notice("请求token->", token)
    --获取应用名称key
    local app_key = "/" .. context_path[1] .. "-" .. host_name[1]
    log.info("获取应用key->", app_key)
    --灰度用户跳转至灰度应用
    if token~=nil then
        if is_gray_user(token) then
            service.request.set_header("host_env", host_name[1])
            set_upstream(conf.zuul_upstream_name, app_key, path)
        end
    end
end

function _M.execute(c)
    conf = c
    local ok, err = do_users()
end

return _M